import React, { Component } from 'react'
import { connect } from 'react-redux'
import { routerActions } from 'react-router-redux'
import { bindActionCreators } from 'redux'
import { fetchCallType, fetchCallId, fetchCallEnd, fetchAddConnectedRecord, fetchCallOut,
  fetchAddCallRecord } from 'actions/common'
import { Button, Input, Form, Row, Col, Modal } from 'antd'
import './ctiContainer.css'

const FormItem = Form.Item
const createForm = Form.create

@connect(
  (state) => ({
    config: state.config,
    callType: state.callType,
    callOut: state.callOut,
  }),
  (dispatch) => ({
    actions: bindActionCreators(routerActions, dispatch),
    dispatch: dispatch,
  })
)

@createForm()
export default class CtiContainer extends Component {
  constructor(props) {
    super(props)
    this.state = {
      ctiUserName: '',
      ctiPassword: '',
      ctiLogonBtnText: '登录',
      ctiLogonProcessing: false,
      ctiLogonSuccess: false,
      ctiMobile: '',
    }

    this.ctiVar = {
      // 来电或外呼号码
      ctiMobile: '',
      // CTI数据库的ID
      ctiCallSheetId: '',
      // 点我吧数据库中的callId
      callId: '',
      // 来电用户的类型：1-收货人、2-商家、3-配送员
      userType: '',
      // 来电用户的id: 收货人电话、商家ID, 配送员ID,
      userId: '',
      // 来电城市Id
      cityId: '',
      // 是否为来电
      isCallIn: false,
      // 查看详情页的操作记录参数
      detailObj: '',
      // 是否请求空闲,防止获取callId的请求被多次发送
      isRequested: true,
      // 是否来自接通的返回值
      isFromConnected: false,
      onLinkCTI: '',
    }

    this.handleChange = this.handleChange.bind(this)
    this.handleKeyDown = this.handleKeyDown.bind(this)
    this.ctiLoginCallback = this.ctiLoginCallback.bind(this)
    this.handleCallOut = this.handleCallOut.bind(this)
    this.handleExitCTI = this.handleExitCTI.bind(this)
    this.handleSimulateCallIn = this.handleSimulateCallIn.bind(this)
    this.handleSimulateConnected = this.handleSimulateConnected.bind(this)
    this.handleSimulateHangUp = this.handleSimulateHangUp.bind(this)
    this.submitForm = this.submitForm.bind(this)
  }

  componentDidMount() {
    if (sessionStorage.getItem('ctiUserName') && sessionStorage.getItem('ctiPassword')) {
      this.ctiLogon(
        sessionStorage.getItem('ctiUserName'),
        sessionStorage.getItem('ctiPassword'),
        this.ctiLoginCallback
      )
    }

    // TODO  测试代码 delete
    const that = this
    window.callIn = function (phoneNum, callsheetId) {
      that.callIn(phoneNum, callsheetId)
    }

    window.hangUp = function () {
      that.hangUp()
    }

    window.ctiConnected = function () {
      that.ctiConnected()
    }
  }

  componentWillReceiveProps(nextProps) {
    const nextCallOut = nextProps.callOut.data
    const propsCallOut = this.props.callOut.data
    if (Object.keys(nextCallOut).length && (nextCallOut.mobile !== propsCallOut.mobile)) {
      this.dialoutCTI(nextCallOut.mobile, nextCallOut)
      // 将callout的中的参数置为空，避免下次从页面中拨打电话时，无法接通
      this.props.dispatch(fetchCallOut({}))
    }
  }

  // 登录CTI
  ctiLogon(userName, passWord, callback) {
    const { config } = this.props
    // eslint-disable-next-line no-undef
    hojo.require('icallcenter.logon')
    // eslint-disable-next-line no-undef
    hojo.require('hojo.io.script')
    // eslint-disable-next-line no-undef
    hojo.addOnLoad(() => {
      // eslint-disable-next-line no-undef
      icallcenter.logon.startLogon(userName, passWord, `http://${config.CTI_SERVER_IP}`, 'sip', callback)
    })
  }

  ctiLoginCallback(logonStatus, user, password) {
    // CTI登录成功
    if (logonStatus === 'logonSuccess') {
      console.log('CTI登录成功>>>>>>>>>>>>>>>>>>>>')
      this.setState({ ctiLogonSuccess: true })
      sessionStorage.setItem('ctiUserName', user)
      sessionStorage.setItem('ctiPassword', password)
    } else {
      // CTI登录失败
      console.log('CTI登录失败>>>>>>>>>>>>>>>>>>>>')
      this.setState({ ctiLogonSuccess: false })
      sessionStorage.setItem('ctiUserName', '')
      sessionStorage.setItem('ctiPassword', '')
    }
    this.setState({ ctiLogonBtnText: '登录' })
    this.setState({ ctiLogonProcessing: false })
  }

  handleChange(event) {
    const newState = {}
    newState[event.target.name] = event.target.value
    this.setState(newState)
  }

  // [回车]
  handleKeyDown(event) {
    if (event.keyCode === 13) {
      this.handleCallOut()
    }
  }

  handleCallOut() {
    this.dialoutCTI(this.state.ctiMobile)
  }

  handleExitCTI() {
    this.setState({ ctiLogonSuccess: false })
    sessionStorage.setItem('ctiUserName', '')
    sessionStorage.setItem('ctiPassword', '')
    this.exitCTI()
  }

  submitForm(e) {
    e.preventDefault()
    this.setState({
      ctiLogonBtnText: '登录中...',
    })
    this.setState({
      ctiLogonProcessing: true,
    })
    const formData = this.props.form.getFieldsValue()
    if (formData.ctiUserName || formData.ctiPassword) {
      this.ctiLogon(formData.ctiUserName, formData.ctiPassword, this.ctiLoginCallback)
    }
  }

  // TODO test code
  handleSimulateCallIn() {
    window.callIn('18814867324', 1)
  }

  handleSimulateConnected() {
    window.onLinkCTI = true
    window.ctiConnected()
  }

  handleSimulateHangUp() {
    window.onLinkCTI = false
    window.hangUp()
  }

  // 来电
  callIn(mobile, callsheetId) {
    console.log('callIn>>>>>>>>>>>>>>>>')
    this.ctiVar.ctiMobile = mobile
    this.ctiVar.ctiCallSheetId = callsheetId
    sessionStorage.setItem('isCallIn', true)
    const that = this

    this.props.dispatch(fetchCallType({ mobile: mobile }, (result) => {
      that.callTypeUpdate(result.data.userType)
    }))
  }

  callTypeUpdate(userType) {
    const { config } = this.props
    this.ctiVar.userType = userType.type
    this.ctiVar.userId = userType.id
    this.ctiVar.cityId = userType.cityId
    const that = this

    // 防止多次发送请求
    if (this.ctiVar.isRequested) {
      // 获取callId
      const params = {
        userType: userType.type,
        userId: userType.id,
        type: config.CALL_TYPE[0].code,
        mobile: this.ctiVar.ctiMobile,
        ctiCallId: this.ctiVar.ctiCallSheetId,
      }
      this.props.dispatch(fetchCallId(params, (result) => {
        that.callIdUpdate(result.data.id)
      }))
      this.ctiVar.isRequested = false
    }
  }

  callIdUpdate(callId) {
    this.ctiVar.callId = callId
    sessionStorage.setItem('callId', callId)
    if (sessionStorage.getItem('isCallIn') === 'true') {
      // 来电弹屏，根据来电类型，跳转至不同类型的详情页
      const { userId, cityId, ctiMobile } = this.ctiVar
      switch (+this.ctiVar.userType) {
        // 收货人
      case 1:
        this.props.actions.push(`/consigneeDetail/${ctiMobile}`)
        break
        // 商家
      case 2:
        this.props.actions.push(`/shopDetail/${userId}/${cityId}`)
        break
        // 配送员
      case 3:
        this.props.actions.push(`/riderDetail/${userId}/${cityId}`)
        break
      default:
        break
      }
      this.ctiVar.isRequested = true
    } else {
      // 外呼
      // TODO to be continued
      this.callOut(this.ctiVar.ctiMobile)
    }
  }

  // 拨打电话
  dialoutCTI(mobile, dObj) {
    if (!this.state.ctiLogonSuccess) {
      Modal.error({
        title: '未登录',
        content: '请登录！',
      })
      return
    }
    const { config } = this.props
    const that = this
    this.ctiVar.ctiMobile = mobile
    this.ctiVar.detailObj = dObj
    const params = {
      type: config.CALL_TYPE[1].code,
      mobile: mobile,
      userId: dObj ? dObj.entityId : 0,
      userType: dObj ? dObj.callUserType : config.CALL_USER_TYPE[0].code,
    }

    this.props.dispatch(fetchCallId(params, (result) => {
      that.callIdUpdate(result.data.id)
    }))

    sessionStorage.setItem('isCallIn', false)
    document.getElementById('icallcenter.dialout.input').value = mobile
  }

  // 外呼
  callOut(mobile) {
    // 这里原来是传vMobile的，但是貌似会导致无法接通，先删掉
    // let vMobile = "88223300"
    // @param vMobile：透传号码
    // eslint-disable-next-line no-undef
    softphoneBar.dialout(mobile)
  }

  // 挂断
  hangUp() {
    const that = this
    const callId = sessionStorage.getItem('callId')

    // 更新通话状态，默认失败->成功
    if (sessionStorage.getItem('isCallIn') === 'true') {
      setTimeout(() => {
        // TODO setTimeout could be replaced by other solutions
        callId && this.props.dispatch(fetchCallEnd({
          id: callId,
          state: 1,
        }, () => {
          that.callEndUpdate()
        }))
      }, 1000)
    } else {
      callId && this.props.dispatch(fetchCallEnd({
        id: callId,
        state: 1,
      }))
    }
  }

  callEndUpdate() {
    this.ctiVar.callId = ''
    // may have some other letiances need to be removed
    sessionStorage.removeItem('callId')
    sessionStorage.removeItem('isCallIn')
    console.log('更新通话状态成功!>>>>>>>>>>>>>>>>')
  }

  // 接通
  ctiConnected() {
    console.log('接通 outer*********************************')
    const { config } = this.props
    // 接通，添加操作记录
    const params = {
      operAct: config.CALL_OP_EVENT_TYPE[2].code,
      callId: sessionStorage.getItem('callId'),
    }
    this.ctiVar.isFromConnected = true
    const that = this

    // 来电, 无法获悉一个CTI接通的响应延迟时间，所以要在获取callId以后回调
    if (sessionStorage.getItem('isCallIn') === 'true') {
      setTimeout(() => {
        params.callId && this.props.dispatch(fetchAddConnectedRecord(params, that.addConnectedRecordUpdate()))
      }, 1000)
    } else {
      // 外呼添加操作记录
      params.callId && this.props.dispatch(fetchAddConnectedRecord(params))
    }
  }

  addConnectedRecordUpdate() {
    const { detailObj, isFromConnected } = this.ctiVar
    const isCallIn = sessionStorage.getItem('isCallIn')
    // 如果是从商家、骑士、订单详情页拨打电话，接通后，添加操作记录
    if (!isFromConnected && !(isCallIn === 'true')
      && detailObj && detailObj.isfromDetailPage) {
      // TODO test!!!!!!
      this.addCallRecord({
        callId: sessionStorage.getItem('callId'),
        detail: detailObj.detail,
        operAct: detailObj.operate,
        entityId: detailObj.entityId,
        entityType: detailObj.entityType,
      })
    }
    this.ctiVar.isFromConnected = false
  }

  /**
   * 通话过程中切换页面到订单详情页，需要添加操作记录
   *
   * @param params
   *        - keys
   *          - {String|Number} id
   *          - {String|Number} operAct
   *          - {String|Number} entityType
   */
  addCallRecord(params) {
    // 来电, 无法获悉一个CTI接通的响应延迟时间，所以要在获取callId以后回调
    params.callId - sessionStorage.getItem('callId')
    params.detail = params.id
    params.entityId = params.id

    if (sessionStorage.getItem('isCallIn') === 'true') {
      setTimeout(() => {
        params.callId = sessionStorage.getItem('callId')
        params.callId && this.props.dispatch(fetchAddCallRecord(params))
      }, 1000)
    } else {
      params.callId && this.props.dispatch(fetchAddCallRecord(params))
    }
  }

  phoneHangUp() {
    window.onLinkCTI = false
    // eslint-disable-next-line no-undef
    phone.hangup()
  }

  phoneHold() {
    // eslint-disable-next-line no-undef
    phone.hold()
  }

  phoneUnHold() {
    // eslint-disable-next-line no-undef
    phone.unhold()
  }

  softphoneBarToTransfer() {
    // eslint-disable-next-line no-undef
    softphoneBar.toTransfer()
  }

  phoneTransfer() {
    // eslint-disable-next-line no-undef
    phone.transfer('912345', 'external', {})
  }

  softphoneBarToConsult() {
    // eslint-disable-next-line no-undef
    softphoneBar.toConsult()
  }

  phoneStopConsult() {
    // eslint-disable-next-line no-undef
    phone.stopConsult()
  }

  softphoneBarToThreeWayCall() {
    // eslint-disable-next-line no-undef
    softphoneBar.toThreeWayCall()
  }

  phoneThreeWayCall() {
    // eslint-disable-next-line no-undef
    phone.threeWayCall('912345')
  }

  phoneSetBusy(e) {
    const id = e.currentTarget.getAttribute('id')
    let flag
    let state
    switch (id) {
    case 'IdleDisable':
      flag = false
      state = '0'
      break
    case 'RestDisable':
      flag = true
      state = '2'
      break
    case 'BusyDisable':
      flag = true
      state = '1'
      break
    default:
      break
    }
    // eslint-disable-next-line no-undef
    phone.setBusy(flag, state)
  }

  exitCTI() {
    // eslint-disable-next-line no-undef
    if (phone) {
      // eslint-disable-next-line no-undef
      phone.destroy(true)
    }
  }

  render() {
    const { config } = this.props
    const { getFieldProps } = this.props.form

    return (
      <Row>
        <Col className={!this.state.ctiLogonSuccess ? '' : 'hidden'} span={12}
          style={{ position: 'absolute', marginLeft: 0 }}
        >
          <Form inline onSubmit={this.submitForm}>
            <FormItem label="用户名:">
              <Input disabled={this.state.ctiLogonProcessing}
                {...getFieldProps('ctiUserName')}
                placeholder="XXXXXX@dwb"
              />
            </FormItem>
            <FormItem label="密码:">
              <Input disabled={this.state.ctiLogonProcessing} type="password"
                {...getFieldProps('ctiPassword')}
              />
            </FormItem>
            <Button type="primary" htmlType="submit"
              disabled={this.state.ctiLogonProcessing}
            >{this.state.ctiLogonBtnText}</Button>
          </Form>
        </Col>
        <Col id="softphonebar" span={12} className={this.state.ctiLogonSuccess ? '' : 'hidden'}
          style={{ position: 'absolute', marginLeft: 0 }}
        >
          <div className="barBox" id="softphonebarBox">
            <div className="softphone_timer">
              <div id="softphonebar.peerState" style={{ float: 'left' }} />
              <div id="softphonebar.peerTimeState" className="peerTimeState" style={{ float: 'left' }}>00:00:00</div>
            </div>
            <input name="ctiMobile" type="text" id="icallcenter.dialout.input" placeholder="输入手机号码"
              onChange={this.handleChange}
              onKeyDown={this.handleKeyDown} className="inp1 fl"
            />
            <a className="DialEnable" id="DialEnable" onClick={this.handleCallOut} />
            <a className="DialDisable" id="DialDisable" style={{ display: 'none' }} />
            <a className="HangupEnable" id="HangupEnable" style={{ display: 'none' }} onClick={this.phoneHangUp} />
            <a className="HangupDisable" id="HangupDisable" />
            <a className="HoldEnable" id="HoldEnable" style={{ display: 'none' }} onClick={this.phoneHold} />
            <a className="HoldDisable" id="HoldDisable" />
            <a className="HoldGetEnable" id="HoldGetEnable" style={{ display: 'none' }} onClick={this.phoneUnHold} />
            <a className="TransferEnable" id="TransferEnable" style={{ display: 'none' }}
              onClick={this.softphoneBarToTransfer}
            />
            <a className="TransferDisable" id="TransferDisable" />
            <a className="TransferEnable" id="ConsultTransferEnable" style={{ display: 'none' }}
              onClick={this.phoneTransfer}
            />
            <a className="TransferDisable" id="ConsultTransferDisable" style={{ display: 'none' }} />
            <a className="ConsultEnable" id="ConsultEnable" style={{ display: 'none' }}
              onClick={this.softphoneBarToConsult}
            />
            <a className="ConsultDisable" id="ConsultDisable" />
            <a className="StopConsultEnable" id="StopConsultEnable" style={{ display: 'none' }}
              onClick={this.phoneStopConsult}
            />
            <a className="ThreeWayCallEnable" id="ThreeWayCallEnable" style={{ display: 'none' }}
              onClick={this.softphoneBarToThreeWayCall}
            />
            <a className="ThreeWayCallDisable" id="ThreeWayCallDisable" />
            <a className="ThreeWayCallEnable" id="ConsultThreeWayCallEnable" style={{ display: 'none' }}
              onClick={this.phoneThreeWayCall}
            />
            <a className="ThreeWayCallDisable" id="ConsultThreeWayCallDisable" style={{ display: 'none' }} />
            <div className="barBox" id="peerStatus">
              <a id="IdleEnable" className="IdleEnable" style={{ display: 'none' }} />
              <a onClick={this.phoneSetBusy} id="IdleDisable" className="IdleDisable" />
              <a id="RestEnable" className="RestEnable" style={{ display: 'none' }} />
              <a onClick={this.phoneSetBusy} id="RestDisable" className="RestDisable" />
              <a id="BusyEnable" className="BusyEnable" />
              <a onClick={this.phoneSetBusy} id="BusyDisable" className="BusyDisable" style={{ display: 'none' }} />
            </div>
            <button onClick={this.handleExitCTI} type="button" className="btn btn-default btn-call-logout">退出</button>
          </div>
        </Col>
        <ul className="nav navbar-top-links pull-right hidden">
          <li id="dropdown-user" className="dropdown">
            <div className="dropdown-menu dropdown-menu-md dropdown-menu-right with-arrow panel-default">
              <div className="pad-all text-right">
                <a onClick={this.handleSimulateCallIn} className="btn btn-primary">
                  <i className="fa fa-sign-out fa-fw" /> 模拟来电
                </a>
              </div>
              <div className="pad-all text-right">
                <a onClick={this.handleSimulateConnected} className="btn btn-primary">
                  <i className="fa fa-sign-out fa-fw" /> 模拟接通
                </a>
              </div>
              <div className="pad-all text-right">
                <a onClick={this.handleSimulateHangUp} className="btn btn-primary">
                  <i className="fa fa-sign-out fa-fw" /> 模拟挂断
                </a>
              </div>
              <div className="pad-all text-right">
                <a href={config.LOGOUT_URL} className="btn btn-primary">
                  <i className="fa fa-sign-out fa-fw" /> 退出
                </a>
              </div>
            </div>
          </li>
        </ul>
      </Row>
    )
  }
}
